<template>
  <div class="code-editor-container">
    <div class="editor-toolbar">
      <div class="toolbar-left">
        <div class="toolbar-group">
          <span class="toolbar-label">语言</span>
          <a-select 
            v-model:value="selectedLanguage" 
            @change="hj_handleLanguageChange"
            class="toolbar-select"
            placeholder="选择语言"
          >
            <a-select-option value="java">
              <span class="option-content">
                <span class="option-icon">☕</span>
                Java
              </span>
            </a-select-option>
            <a-select-option value="json">
              <span class="option-content">
                <span class="option-icon">📄</span>
                JSON
              </span>
            </a-select-option>
          </a-select>
        </div>
        
        <div class="toolbar-group">
          <span class="toolbar-label">主题</span>
          <select 
            v-model="selectedTheme" 
            @change="hj_handleThemeChange"
            class="theme-select"
          >
            <option value="light">☀️ 浅色主题</option>
            <option value="dark">🌙 深色主题</option>
          </select>
        </div>
      </div>
      
      <div class="toolbar-right">
        <a-button 
          v-if="selectedLanguage === 'json'"
          @click="hj_compressJson" 
          type="default" 
          class="compress-button"
        >
          <span class="button-icon">📦</span>
          压缩JSON
        </a-button>
        <a-button 
          v-if="selectedLanguage === 'json'"
          @click="hj_formatJson" 
          type="default" 
          class="format-button"
        >
          <span class="button-icon">✨</span>
          格式化JSON
        </a-button>
        <a-button 
          @click="hj_clearContent" 
          type="primary" 
          danger
          class="clear-button"
        >
          <span class="button-icon">🗑️</span>
          清空内容
        </a-button>
      </div>
    </div>
    
    <div ref="editorElement" class="editor-content"></div>
  </div>
</template>

<script>
import { ref, onMounted, onUnmounted, watch } from 'vue'
import { EditorView, keymap, highlightActiveLineGutter, lineNumbers, highlightActiveLine } from '@codemirror/view'
import { EditorState } from '@codemirror/state'
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands'
import { foldGutter, indentOnInput, bracketMatching, foldKeymap } from '@codemirror/language'
import { java } from '@codemirror/lang-java'
import { json } from '@codemirror/lang-json'
import { oneDark } from '@codemirror/theme-one-dark'
import { linter, lintGutter } from '@codemirror/lint'

export default {
  name: 'CodeEditor',
  props: {
    modelValue: {
      type: String,
      default: ''
    }
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const editorElement = ref(null)
    const selectedLanguage = ref('java')
    const selectedTheme = ref('dark')
    let editor = null

    // JSON错误标记相关
    const jsonLinter = linter((view) => {
      if (selectedLanguage.value !== 'json') {
        return []
      }
      
      const content = view.state.doc.toString().trim()
      if (!content) {
        return []
      }
      
      try {
        JSON.parse(content)
        return []
      } catch (error) {
        // 尝试找到错误位置
        const errorPos = hj_findJsonErrorPosition(content, error.message)
        if (errorPos >= 0) {
          return [{
            from: errorPos,
            to: errorPos + 1,
            severity: 'error',
            message: error.message
          }]
        }
        
        // 如果找不到具体位置，在文档末尾标记
        return [{
          from: content.length - 1,
          to: content.length,
          severity: 'error',
          message: error.message
        }]
      }
    })


    /**
     * 获取语言支持
     * @param {string} language - 语言类型
     * @returns {object} 语言支持对象
     */
    const hj_getLanguageSupport = (language) => {
      const languageMap = {
        java: java(),
        json: json()
      }
      return languageMap[language] || java()
    }

    /**
     * 获取主题配置
     * @param {string} theme - 主题类型
     * @returns {array} 主题配置数组
     */
    const hj_getThemeConfig = (theme) => {
      return theme === 'dark' ? [oneDark] : []
    }

    /**
     * 获取基础扩展配置
     * @returns {array} 基础扩展数组
     */
    const hj_getBasicExtensions = () => {
      return [
        lineNumbers(),
        highlightActiveLineGutter(),
        highlightActiveLine(),
        indentOnInput(),
        bracketMatching(),
        foldGutter(),
        history(),
        lintGutter(), // 添加lint gutter
        jsonLinter, // 添加JSON linter
        keymap.of([
          ...defaultKeymap,
          ...historyKeymap,
          ...foldKeymap
        ]),
        EditorView.updateListener.of((update) => {
          if (update.docChanged) {
            const content = update.state.doc.toString()
            emit('update:modelValue', content)
          }
        })
      ]
    }

    /**
     * 初始化编辑器
     */
    const hj_initEditor = () => {
      if (!editorElement.value) return

      const extensions = [
        ...hj_getBasicExtensions(),
        hj_getLanguageSupport(selectedLanguage.value),
        ...hj_getThemeConfig(selectedTheme.value)
      ]

      const startState = EditorState.create({
        doc: props.modelValue || hj_getDefaultContent(selectedLanguage.value),
        extensions
      })

      editor = new EditorView({
        state: startState,
        parent: editorElement.value
      })
    }

    /**
     * 获取默认内容
     * @param {string} language - 语言类型
     * @returns {string} 默认内容
     */
    const hj_getDefaultContent = (language) => {
      const defaultContents = {
        java: `// Java 代码示例
public class HelloWorld {
    private String message;
    
    /**
     * 构造函数
     * @param message 欢迎消息
     */
    public HelloWorld(String message) {
        this.message = message;
    }
    
    /**
     * 获取欢迎消息
     * @return 欢迎消息字符串
     */
    public String hj_getMessage() {
        return this.message;
    }
    
    /**
     * 设置欢迎消息
     * @param message 新的欢迎消息
     */
    public void hj_setMessage(String message) {
        this.message = message;
    }
    
    /**
     * 主方法
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        HelloWorld hello = new HelloWorld("欢迎使用 Java 代码编辑器！");
        System.out.println(hello.hj_getMessage());
        
        // 演示循环和条件语句
        for (int i = 1; i <= 5; i++) {
            if (i % 2 == 0) {
                System.out.println("偶数: " + i);
            } else {
                System.out.println("奇数: " + i);
            }
        }
    }
}`,
        json: `{
  "name": "我爱海鲸-代码编辑器",
  "version": "1.0.0",
  "description": "专业程序员开发环境",
  "author": {
    "name": "海鲸",
    "email": "haijin@example.com"
  },
  "features": [
    "语法高亮",
    "智能提示",
    "多语言支持",
    "主题切换",
    "代码折叠"
  ],
  "supportedLanguages": {
    "java": {
      "icon": "☕",
      "description": "Java 编程语言"
    },
    "json": {
      "icon": "📄",
      "description": "JSON 数据格式"
    }
  },
  "settings": {
    "theme": "dark",
    "fontSize": 14,
    "tabSize": 2,
    "autoSave": true
  },
  "statistics": {
    "totalLines": 0,
    "totalCharacters": 0,
    "lastModified": null
  }
}`
      }
      return defaultContents[language] || defaultContents.java
    }

    /**
     * 处理语言切换
     * @param {string} language - 新选择的语言
     */
    const hj_handleLanguageChange = (language) => {
      if (editor) {
        const newContent = hj_getDefaultContent(language)
        editor.dispatch({
          changes: {
            from: 0,
            to: editor.state.doc.length,
            insert: newContent
          }
        })
      }
    }

    /**
     * 处理主题切换
     * @param {string} theme - 新选择的主题
     */
    const hj_handleThemeChange = (theme) => {
      console.log('切换主题到:', theme)
      if (editor) {
        // 保存当前内容
        const currentContent = editor.state.doc.toString()
        
        // 销毁当前编辑器
        editor.destroy()
        editor = null
        
        // 清空编辑器容器
        if (editorElement.value) {
          editorElement.value.innerHTML = ''
        }
        
        // 重新创建编辑器以应用新主题
        setTimeout(() => {
          hj_initEditor()
          
          // 恢复内容
          if (editor && currentContent) {
            editor.dispatch({
              changes: {
                from: 0,
                to: editor.state.doc.length,
                insert: currentContent
              }
            })
          }
        }, 50)
      }
    }



    /**
     * 查找JSON错误位置
     * @param {string} content - JSON内容
     * @param {string} errorMessage - 错误信息
     * @returns {number} 错误位置
     */
    const hj_findJsonErrorPosition = (content, errorMessage) => {
      // 简单的错误位置查找逻辑
      // 可以根据错误信息进行更精确的定位
      const match = errorMessage.match(/position (\d+)/)
      if (match) {
        return parseInt(match[1])
      }
      
      // 如果没有位置信息，尝试查找常见的错误模式
      const lines = content.split('\n')
      for (let i = 0; i < lines.length; i++) {
        const line = lines[i]
        // 查找常见的JSON错误模式
        if (line.includes('undefined') || 
            line.includes('NaN') || 
            line.includes('Infinity') ||
            line.match(/[^\\]"/) && !line.match(/[^\\]":/)) {
          return content.indexOf(line)
        }
      }
      
      return -1
    }

    /**
     * 压缩JSON内容
     */
    const hj_compressJson = () => {
      if (!editor) return
      
      const currentContent = editor.state.doc.toString().trim()
      if (!currentContent) {
        hj_showMessage('编辑器内容为空，无法压缩', 'warning')
        return
      }
      
      try {
        // 解析JSON
        const jsonObject = JSON.parse(currentContent)
        
        // 压缩JSON（移除所有空格和换行）
        const compressedJson = JSON.stringify(jsonObject)
        
        // 更新编辑器内容
        editor.dispatch({
          changes: {
            from: 0,
            to: editor.state.doc.length,
            insert: compressedJson
          }
        })
        
        hj_showMessage('JSON压缩成功！', 'success')
      } catch (error) {
        hj_showMessage(`JSON格式错误：${error.message}`, 'error')
      }
    }

    /**
     * 格式化JSON内容
     */
    const hj_formatJson = () => {
      if (!editor) return
      
      const currentContent = editor.state.doc.toString().trim()
      if (!currentContent) {
        hj_showMessage('编辑器内容为空，无法格式化', 'warning')
        return
      }
      
      try {
        // 解析JSON
        const jsonObject = JSON.parse(currentContent)
        
        // 格式化JSON（2个空格缩进）
        const formattedJson = JSON.stringify(jsonObject, null, 2)
        
        // 更新编辑器内容
        editor.dispatch({
          changes: {
            from: 0,
            to: editor.state.doc.length,
            insert: formattedJson
          }
        })
        
        hj_showMessage('JSON格式化成功！', 'success')
      } catch (error) {
        hj_showMessage(`JSON格式错误：${error.message}`, 'error')
      }
    }

    /**
     * 显示消息提示
     * @param {string} message - 消息内容
     * @param {string} type - 消息类型
     */
    const hj_showMessage = (message, type = 'info') => {
      // 这里可以集成ant-design的消息组件
      // 暂时使用console输出
      console.log(`[${type.toUpperCase()}] ${message}`)
      
      // 简单的浏览器通知
      if (type === 'error') {
        alert(`错误：${message}`)
      } else if (type === 'success') {
        // 可以添加成功提示的样式
        console.log(`✅ ${message}`)
      } else if (type === 'warning') {
        alert(`警告：${message}`)
      }
    }

    /**
     * 清空编辑器内容
     */
    const hj_clearContent = () => {
      if (editor) {
        editor.dispatch({
          changes: {
            from: 0,
            to: editor.state.doc.length,
            insert: ''
          }
        })
      }
    }

    // 监听props变化
    watch(() => props.modelValue, (newValue) => {
      if (editor && newValue !== editor.state.doc.toString()) {
        editor.dispatch({
          changes: {
            from: 0,
            to: editor.state.doc.length,
            insert: newValue
          }
        })
      }
    })

    onMounted(() => {
      hj_initEditor()
    })

    onUnmounted(() => {
      if (editor) {
        editor.destroy()
      }
    })

    return {
      editorElement,
      selectedLanguage,
      selectedTheme,
      hj_handleLanguageChange,
      hj_handleThemeChange,
      hj_compressJson,
      hj_formatJson,
      hj_clearContent
    }
  }
}
</script>

<style scoped>
.code-editor-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #fff;
}

.editor-toolbar {
  padding: 16px 24px;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
  border-bottom: 1px solid #e2e8f0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 24px;
}

.toolbar-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

.toolbar-label {
  font-size: 14px;
  font-weight: 600;
  color: #475569;
  min-width: 40px;
}

.toolbar-select {
  min-width: 140px;
}

.theme-select {
  min-width: 140px;
  height: 32px;
  padding: 4px 8px;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  background: #fff;
  font-size: 14px;
  color: #262626;
  cursor: pointer;
  outline: none;
  transition: all 0.3s;
}

.theme-select:hover {
  border-color: #40a9ff;
}

.theme-select:focus {
  border-color: #40a9ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}


.toolbar-right {
  display: flex;
  align-items: center;
}

.compress-button {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  border-radius: 8px;
  padding: 8px 16px;
  height: 36px;
  margin-right: 12px;
  background: linear-gradient(135deg, #52c41a 0%, #389e0d 100%);
  border: none;
  color: white;
  transition: all 0.3s ease;
}

.compress-button:hover {
  background: linear-gradient(135deg, #48a016 0%, #2f7a0a 100%);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(82, 196, 26, 0.4);
}

.format-button {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  border-radius: 8px;
  padding: 8px 16px;
  height: 36px;
  margin-right: 12px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  color: white;
  transition: all 0.3s ease;
}

.format-button:hover {
  background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}

.clear-button {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  border-radius: 8px;
  padding: 8px 16px;
  height: 36px;
}

.button-icon {
  font-size: 14px;
}

.editor-content {
  flex: 1;
  overflow: hidden;
  background: #fff;
}

:deep(.cm-editor) {
  height: 100%;
  font-size: 14px;
  border-radius: 0;
}

:deep(.cm-scroller) {
  font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', 'Source Code Pro', monospace;
}

:deep(.cm-focused) {
  outline: none;
}

:deep(.cm-editor .cm-content) {
  padding: 16px;
}

:deep(.cm-editor .cm-line) {
  line-height: 1.6;
}

/* JSON错误标记样式 */
:deep(.cm-lint-marker-error) {
  background-color: #ff4d4f;
  border-radius: 50%;
  width: 8px;
  height: 8px;
  display: inline-block;
  margin-right: 4px;
}

:deep(.cm-lint-marker-error::after) {
  content: '⚠️';
  position: absolute;
  right: -20px;
  top: -2px;
  font-size: 12px;
  color: #ff4d4f;
}

:deep(.cm-lint-range-error) {
  background-color: rgba(255, 77, 79, 0.1);
  border-bottom: 2px solid #ff4d4f;
  border-radius: 2px;
}

:deep(.cm-lint-range-error::after) {
  content: '⚠️';
  position: absolute;
  right: -20px;
  top: -2px;
  font-size: 12px;
  color: #ff4d4f;
}

/* 选择器选项样式 */
:deep(.ant-select-item-option-content) {
  display: flex;
  align-items: center;
  gap: 8px;
}

.option-content {
  display: flex;
  align-items: center;
  gap: 8px;
}

.option-icon {
  font-size: 16px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .editor-toolbar {
    flex-direction: column;
    gap: 16px;
    padding: 16px;
  }
  
  .toolbar-left {
    flex-direction: column;
    gap: 16px;
    width: 100%;
  }
  
  .toolbar-group {
    width: 100%;
    justify-content: space-between;
  }
  
  .toolbar-select {
    min-width: 120px;
  }
  
  .toolbar-right {
    width: 100%;
    justify-content: center;
    gap: 8px;
    flex-wrap: wrap;
  }
  
  .compress-button {
    flex: 1;
    justify-content: center;
    margin-right: 0;
    min-width: 120px;
  }
  
  .format-button {
    flex: 1;
    justify-content: center;
    margin-right: 0;
    min-width: 120px;
  }
  
  .clear-button {
    flex: 1;
    justify-content: center;
    min-width: 120px;
  }
}
</style>
